import commonConstants from "@/common/commonConstants";
import commonMethod from "@/common/commonMethod";
import { Color, defined, HeadingPitchRoll, HeightReference, LabelStyle, Math } from "cesium";
import radarPath from '@/assets/source/pointPng/radar.png'
import radarModel from '@/assets/source/model/2m.GLTF'

class TroopManager{
    constructor(v,configs,effectM,monitorM){

        this.curViewer = v;

        this.isAllShow = true;
        //是否以显示，false以3D模型显示
        this.isScutcheonShow = false;
        
        this.effectManager = effectM;
        
        this.troopMap = new Map();
        this.troopMap.set(commonConstants.troopCamp.our_side,[]);
        this.troopMap.set(commonConstants.troopCamp.our_enemy,[]);
        this.troopMap.set(commonConstants.troopCamp.our_friend,[]);

        this.troopGroups = new Map();
        this.troopGroups.set(commonConstants.troopCamp.our_side,[]);
        this.troopGroups.set(commonConstants.troopCamp.our_enemy,[]);
        this.troopGroups.set(commonConstants.troopCamp.our_friend,[]);
        //支持添加兵力类型
        this.troopTypes = [];

        this.monitorManager = monitorM;
        this.troopMonitor = monitorM.getMonitorByKey(commonConstants.monitorKey.troop);
        this.troopMonitor.setTroopManager(this);
        this.layerManager = undefined;

        this._handlerConfigs(configs);
        this._initTroopTypes();
    }
     //处理一些配置信息
     _handlerConfigs(configs){
        if (configs) {
             //没有就不处理
            configs.forEach(config => {
                if(config.getKey() == commonConstants.configurationKey.troop){
                    this.attributePlane = config.getValue();
                }
            });     
        }
    
    }

    /**
     * 初始化所有的类型
     */
    _initTroopTypes(){
        this.troopTypes.push(
            new TroopType(commonConstants.troopType.radar,{
                troopTypeName:"雷达",
                carryLevel:0,
                scutcheon:radarPath,
                model:radarModel,
                effects:[commonConstants.effectType.PHASED_ARRAY_RADAR]
            })
        );
    }

    setLayerManager(layerm){
        this.layerManager = layerm;
    }

     /**
     *
     * @return {(Troop)[]}
     */
     getAllTroops(){
        let _this =this;
        let allTroops = [];
        for (let key of _this.troopMap.keys()){
            let troops = _this.troopMap.get(key);
            for (let i = 0; i < troops.length; i++) {
                allTroops.push(troops[i]);
            }
        }
        return allTroops;
    }
    /**
     *
     * @return {TroopListecner}
     */
    getTroopMonitor(){
        let _this = this;
        return _this.troopMonitor;
    }

    deployTroopMonitor(op,callback){
        const _this = this;
        _this.troopMonitor.setParams(op)
        _this.troopMonitor.setCallbackFunction(callback);
        _this.monitorManager.deployMonitor(_this.troopMonitor);
    }
 
    /**
     *
     * @return {(TroopType)[]}
     */
    getAllTypes(){
        let _this = this;
        return _this.troopTypes;
    }
    /**
     *
     * @param troopTypeId
     * @return {TroopType}
     */
    getTroopTypeById(troopTypeId){
        let _this = this;
        return commonMethod.findElementFromArray(_this.troopTypes,t=>t.getID() == troopTypeId);
    }
    logut (troopType) {
        let _this = this;
        let index  = _this.troopTypes.indexOf(troopType);
        if(index != -1){
            _this.troopTypes.splice(index,1)
        }
    }
    createTroopByTroopTypeId(troopTypeId , options){
        const _this= this;
        return _this.createTroop(_this.getTroopTypeById(troopTypeId),options)
    }
    /**
     * 通过兵力类型创建实例
     * @param troopType 创建兵力的类型
     * @param options 创建兵力的其他参数
     */
    createTroop(troopType,options) {
        let _this=this;  
        const troop = new Troop(options,troopType);
        const effects =  troopType.getEffects().map(e => _this.effectManager.buildEffect(commonConstants.effectType.PHASED_ARRAY_RADAR,troop));
        troop.setEffects(effects);
        _this.addTroop(troop);
        return troop;
    }
    createTroopGrounp(op){
        let _this = this;
        let troopGroup = new TroopGroup(op);
        _this.troopGroups.get(troopGroup.getTroopCamp()).push(troopGroup);
        return troopGroup;
    }
    getTroopsByTroopCamp (camp) {
        let _this =this;
       return _this.troopMap.get(camp);
    }
    getTroopGroups(camp){
        let _this =this;
        return _this.troopGroups.get(camp);
    }
    /**
     *
     * @return {(TroopGroup)[]}
     */
    getAllTroopGroups(){
        let _this =this;
        let allTroopGroups = [];
        for (let key of _this.troopGroups.keys()){
            let troopGroups = _this.troopGroups.get(key);
            for (let i = 0; i < troopGroups.length; i++) {
                allTroopGroups.push(troopGroups[i]);
            }
        }
        return allTroopGroups;
    }
    /**
     * 获得对应的兵力组
     * @param troopGroupId
     * @return {TroopGroup}
     */
    getTroopGroupById(troopGroupId){
        let _this = this;
        let findTroopGroup = undefined;
        for (let key of _this.troopGroups.keys()){
            let troopCampGroups = _this.troopGroups.get(key);
            for (let i = 0; i < troopCampGroups.length; i++) {
                let t = troopCampGroups[i];
                if (t.getTroopGroupId() === troopGroupId){
                    findTroopGroup = t;
                    break;
                }
            }
        }
        return findTroopGroup;
    }
    /**
     *
     * @param troopId
     * @return {Troop}
     */
    getTroopById (troopId) {
        let _this = this;
        let findTroop=null;
        _this.troopMap.forEach((v)=>{
            for (let troop of v){
                if (troop.getTroopId() === troopId){
                    findTroop = troop;
                    break;
                }
            }
        });
        return findTroop;
    }
    /**
     * @param troop {Troop}
     */
    addTroop(troop){
        let _this = this;
        if (troop) {
            let troops = _this.troopMap.get(troop.getTroopCamp());
            if (troops.indexOf(troop) === -1){
                troops.push(troop);
            }
        }
    }
    /**
     * @param troop {Troop}
     */
    removeTroop(troop){
        let _this = this;
        if (troop) {
            let troops = _this.troopMap.get(troop.getTroopCamp());
            let index = troops.indexOf(troop);
            if (index !== -1){

                //属性面板
                // if (_this.scenarioConfiguration.getConfiguration("attributePanelable")){
                //     scenario_deduce.getAttributePanelUtils().removePanelById(troop.getID());
                // }
                //图层管理
                if (_this.layerManager){
                    _this.layerManager.getTroopLayer(troop.getTroopCamp()).remove(troop);
                }

                troop.destroy();
                troops.splice(index,1);
            }
        }
    }
    /**
     * @param troopGroup {TroopGroup}
     */
    addTroopGroup(troopGroup){
        let _this = this;
        if (troopGroup) {
            let troopGroups = _this.troopGroups.get(troopGroup.getTroopCamp());
            if (troopGroups.indexOf(troopGroup) === -1){
                troopGroups.push(troopGroup);
            }

        }
    }
    /**
     * @param troopGroup {TroopGroup}
     */
    removeTroopGroup(troopGroup){
        let _this = this;
        if (troopGroup) {
            let troopGroups = _this.troopGroups.get(troopGroup.getTroopCamp());
            let index = troopGroups.indexOf(troopGroup);
            if (index !== -1){
                //删除兵力组中所有的兵力
                troopGroup.destroy();
                troopGroups.splice(index,1);
            }

        }
    }
    /**
     *
     * @param position {Cartesian3}
     * @param troop {Troop}
     */
    deployTroop(position,troop){
        let _this = this;
        if (position && !troop.getStaticPosition()){
            troop.setStaticPosition(position);
        }

        if (troop.getEntity()){
            troop.setShow(true);
        }else{
            //创建一个兵力
            let color = Color.fromCssColorString(troop.getTroopCamp());

            let troopEntity=_this.curViewer.entities.add({
                id:troop.getTroopId(),
                name:troop.getTroopName(),
                //获得坐标集合
                position:troop.getStaticPosition(),
                //加入模型
                model : {
                    uri :troop.getTroopModel(),
                    minimumPixelSize : 60
                },
                billboard:{
                    image:troop.getTroopScutcheon(),
                    show:_this.isScutcheonShow,
                    scale:0.1
                },
                label:{
                    text:troop.getTroopName(),
                    font: '18px "微软雅黑", Arial, Helvetica, sans-serif, Helvetica',
                    fillColor: color,
                    outlineColor: Color.SKYBLUE,
                    outlineWidth: 1,
                    style: LabelStyle.FILL_AND_OUTLINE,
                    heightReference: HeightReference.CLAMP_TO_GROUND,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY
                }
            });

            troopEntity.monitorKey = commonConstants.monitorKey.troop;
            troopEntity.entityType = commonConstants.entityType.troop;
            troop.setTroopEntity(troopEntity);

            _this.monitorManager.getDefaultMonitor().putEntity(_this.troopEntity);

            //兵力效果的渲染
           troop.effectRender();
            
        }
        troop.setDeploy(true);
        //属性面板
        // if (_this.scenarioConfiguration.getConfiguration("attributePanelable")){
        //     scenario_deduce.getAttributePanelUtils().troopAttributePanel(troop);
        // }
        //图层管理
        if (_this.layerManager){
            _this.layerManager.getTroopLayer(troop.getTroopCamp()).addEntity(troop);
        }
    }

    /**
     *
     * @param position {Cartesian3}
     * @param troopGroup {TroopGroup}
     * @param number {Number}
     */
    deployTroopGroup(position,troopGroup){
        let _this =this;
        let troopArray = troopGroup.getTroopArray();
        for (let i = 0; i < troopArray.length; i++) {
            let troop = troopArray[i];
            _this.deployTroop(position,troop);
        }
    }
    setAllShow(bool){
        let _this =this;
        let allTroops = _this.getAllTroops();
        for (let i = 0; i < allTroops.length; i++) {
            let troop = allTroops[i];
            troop.setShow(bool);
        }
        _this.isAllShow =bool;
    }
    dataClear(){
        let _this = this;
        _this.setAllShow(false);
    }
    destroy(){
        const _this = this;
        _this.clear();
    }
    clear () {
        let _this = this;
        if (_this.troopGroups){
            for (let kay of _this.troopGroups.keys()){
                let troopGroups = _this.troopGroups.get(kay);
                for (let i = 0; i < troopGroups.length; i++) {
                    let troopGroup = troopGroups[i];
                    troopGroup.destroy(_this.curViewer);
                }
            }
        }

        if (_this.troopMap){
            let troops = _this.getAllTroops();
            for (let j =0 ;j< troops.length;j++){
                let troop = troops[j];
                if (!troop.isDestroyed()) {
                    troop.destroy(_this.curViewer);
                }
            }
        }

    }
    reload(scenarioId) {
        let _this = this;
        // const troopsResult = _this.dataStorage.load(CommonConstants.dataOperationType.troop);
        // if (troopsResult){
        //     let troopDatas = troopsResult["troops"];
        //     for (let i = 0; i < troopDatas.length; i++) {
        //         let troopData = troopDatas[i];
        //         let troop1 = _this.createTroop(_this.getTroopTypeById(troopData["troopType"]),troopData);
        //         _this.deployTroop(troop1.getStaticPosition(),troop1);
        //     }
        // }

        // const troopGroupResult = _this.dataStorage.load(CommonConstants.dataOperationType.troopGroup);
        // if (troopGroupResult){
        //     let troopGroupDatas = troopGroupResult["troopGroups"];
        //     for (let j = 0; j < troopGroupDatas.length; j++) {
        //         let troopGroupData = troopGroupDatas[j];
        //         _this.createTroopGrounp(troopGroupData);
        //     }
        // }
        // //关系组建
        // let allTroops = _this.getAllTroops();
        // for (let i = 0; i < allTroops.length; i++) {
        //     let troop = allTroops[i];
        //     //所属兵力
        //     let belongTroop = troop.getBelongTroop();
        //     if (belongTroop){
        //         troop.setBelongTroop(_this.getTroopById(belongTroop));
        //     }

        //     //设置兵力组
        //     let troopGroupId = troop.getTroopGroup();
        //     if (troopGroupId){
        //         troop.setTroopGroup(_this.getTroopGroupById(troopGroupId));
        //     }

        //     //指挥兵力
        //     let commandTroops = troop.getCommandTroops();
        //     troop.clearCommandTroops();
        //     for (let j = 0; j < commandTroops.length; j++) {
        //         troop.getCommandTroops().push(_this.getTroopById(commandTroops[j]))
        //     }

        //     //搭载兵力
        //     let carryTroops = troop.getCarryTroops();
        //     troop.clearCarryTroops();
        //     for (let j = 0; j < carryTroops.length; j++) {
        //         troop.getCarryTroops().push(_this.getTroopById(carryTroops[j]));
        //     }
        // }
    }

}

/**
 * 兵力组，可以批量生产，也支持单独加入
 */
class TroopGroup{
    constructor(options){
      
        this.troopGroupId = commonMethod.creatUUID();
        //默认红方
        this.troopGroupCamp = commonConstants.troopCamp.our_side;
        this.troopArray = [];
        this.troopGroupName = undefined;

        if (options){
            if (options["troopGroupId"]){
                this.troopGroupId = options["troopGroupId"];
            }
            if (options["troopGroupName"]){
                this.troopGroupName = options["troopGroupName"];
            }
            if (options["troopCamp"]){
                this.troopGroupCamp = options["troopCamp"];
            }
        } 
    }

    getTroopGrooupId(){
        let _this = this;
        return _this.troopGroupId;
    }
    getTroopGroupName(){
        let _this = this;
        return _this.troopGroupName;
    }
    setTroopName(name){
        const _this = this;
        _this.troopGroupName = name;
    }
    getTroopCamp(){
      let _this = this;
      return _this.troopGroupCamp;
    }
    setTroopCamp(camp){
        const _this = this;
        _this.troopGroupCamp = camp;
    }
    /**
     *
     * @param troop {Troop}
     */
    addTroop(troop){
        let _this = this;
        let number = _this.troopArray.indexOf(troop);
        if (number === -1){
            _this.troopArray.push(troop);
        }
    }
    removeTroop(troop){
        let _this = this;
        let number = _this.troopArray.indexOf(troop);
        if (number !== -1){
            _this.troopArray.splice(number,1);
        }
    }

    getTotal(){
        const _this = this;
        return _this.troopArray.length;
    }
    /**
     *
     * @return {null|[]|*[]}
     */
    getTroopArray(){
        let _this =this;
        return _this.troopArray;
    }
    destroy(v) {
        let _this = this;
        for (let i = 0; i < _this.troopArray.length; i++) {
            let troop = _this.troopArray[i];
            if (!troop.isDestroyed()) {
                troop.destroy(v);
            }
        }
    }
    toJson() {
        let _this =this;
        return {
            troopGroupId:_this.troopGroupId,
            troopGroupName:_this.troopGroupName,
            troopCamp:_this.troopGroupCamp,
        }
    }


}

/**
 * 兵力类型，可以确定兵力的模型，搭载等级等
 */
class TroopType{
    constructor(troopTypeID , op){
        this.troopTypeId = troopTypeID;
        this.troopTypeName = "未命名";
        //效果的Key
        this.effects = [];
        this.carryLevel = 0;
        this.scutcheon = undefined;
        this.model = undefined;

        if (op){
            if (op["troopTypeName"]){
                this.troopTypeName = op["troopTypeName"];
            }
            if (op["carryLevel"]){
                this.carryLevel = op["carryLevel"];
            }
            if (op["scutcheon"]){
                this.scutcheon = op["scutcheon"];
            }
            if (op["model"]){
                this.model = op["model"];
            }
            if (op["effects"]){
                this.effects = op["effects"]
            }
        }
    }
    getScutcheon(){
        let _this = this;
        return _this.scutcheon;
    }
    getTroopModel(){
        let _this = this;
        return _this.model;
    }
    getTroopTypeId(){
        let _this = this;
        return _this.troopTypeId;
    }
    getID(){
        return this.getTroopTypeId()
    }
    getCarryLevel(){
        const _this = this;
        return _this.carryLevel;
    }
    getTroopTypeName(){
        let _this = this;
        return _this.troopTypeName;
    }
    getEffects(){
        return this.effects;
    }
}

/**
 * 兵力类型
 */
class Troop {
    constructor(options,troopType){

        this.className = "Troop";

        this.commandTroops = undefined;
        this.carryTroops = [];

        this.troopId = commonMethod.creatUUID();
        this.troopCamp = commonConstants.troopCamp.our_side;
        this.state = commonConstants.troopState.Normal;
        this.isDestroyed = false;
        this.isDeployed = false;
        this.isShow = true;
        this.troopType = troopType?troopType:undefined;
        this.carryLevel = troopType?troopType.getCarryLevel():0;
        this.speed = 100;
        this.heading = Math.toRadians(0);
        this.detectionDistance = 30000
     
        this.troopName = "未命名";
        this.troopScutcheon = troopType?troopType.getScutcheon():undefined;
        this.troopModel = troopType?troopType.getTroopModel():undefined;
        this.staticPosition = undefined;
        this.dynamicPosition = undefined;
        this.troopGroup = undefined;
        this.commandTroop = undefined;
        this.belongTroop = undefined;
        this.troopEntity = undefined;
       
        this.effects = [];

        if (options){
            if (options["troopId"]){
                this.troopId = options["troopId"];
            }
            if (options["name"]){
                this.troopName = options["name"]
            }
            if (options["troopName"]){
                this.troopName = options["troopName"];
            }
            if (options["troopType"]){
                this.troopType = options["troopType"];
            }
            if (options["carryLevel"]){
                this.carryLevel = options["carryLevel"];
            }
            if (options["camp"]){
                this.troopCamp = options["camp"];
            }
            if (options["troopCamp"]){
                this.troopCamp = options["troopCamp"];
            }
            if (options["speed"]){
                this.speed = options["speed"];
            }
            if (options["detectionDistance"]){
                this.detectionDistance = options["detectionDistance"];
            }
            if (options["troopScutcheon"]){
                this.troopScutcheon = options["troopScutcheon"];
            }
            if (options["troopModel"]){
                this.troopModel = options["troopModel"];
            }
            if (options["modelPath"]){
                this.troopModel = options["modelPath"];
            }
            if (options["troopPosition"]){
                if(defined(options["troopPosition"])){
                    this.staticPosition = options["troopPosition"];
                }else{
                    this.staticPosition = commonMethod.reCodingPostion(options["troopPosition"]);
                }
            }
            if (options["belongTroop"]){
                this.belongTroop = options["belongTroop"];
            }
            if (options["commandTroop"]){
                this.commandTroop =options["commandTroop"];
            }
            if (options["troopGroup"]){
                this.troopGroup = options["troopGroup"];
            }

            if(options["effects"]){
                this.effects = options["effects"]
            }
        }
    }

    getID(){
        let _this = this;
        return _this.troopId;
    }
    getTroopId(){
        let _this = this;
        return _this.troopId;
    }

    /**
     *
     * @return {TroopType}
     */
    getTroopType(){
        let _this =this;
        return _this.troopType;
    }
    /**
     * 
     * @param {TroopType} troopType 
     */
    setTroopType(troopType){
        let _this = this;
        _this.troopType = troopType;
        if (!_this.troopScutcheon){
            _this.troopScutcheon = troopType.getScutcheon();
        }
        if (!_this.troopModel){
            _this.troopModel = troopType.getTroopModel();
        }
    }
    getTroopName(){
        let _this =this;
        return _this.troopName;
    }
    getTroopCamp(){
        let _this =this;
        return _this.troopCamp;
    }
    /**
     *
     * @return {null|Troop}
     */
    getBelongTroop(){
        let _this = this;
        return _this.belongTroop;
    }
    setBelongTroop(belongTroop){
        let _this = this;
        _this.belongTroop = belongTroop;
    }
    getEntity(){
        let _this =this;
        return _this.troopEntity;
    }
    setTroopEntity(troopEntity){
        let _this = this;
        _this.troopEntity = troopEntity;
    }
    getStaticPosition(){
        let _this = this;
        return _this.staticPosition;
    }
    setStaticPosition(pos){
        let _this = this;
        _this.staticPosition = pos;
    }
    getTroopModel(){
      let _this =this;
      return _this.troopModel;
    }
    setTroopModel(modelPath){
        let _this =this;
        _this.troopModel = modelPath;
    }
    getTroopScutcheon(){
        let _this = this;
        return _this.troopScutcheon;
    }
    /**
     *
     * @return {null|[]|*[]|*}
     */
    getCommandTroop(){
        let _this = this;
        return _this.commandTroops;
    }
    /**
     *
     * @return {null|[]|(Troop)[]}
     */
    getCarryTroops(){
        let _this = this;
        return _this.carryTroops;
    }
    clearCarryTroops(){
        let _this = this;
        _this.carryTroops.splice(0,_this.carryTroops.length);
    }
    setDeploy(bool){
        let _this = this;
        _this.isDeployed = bool;
    }
    getIsDeploy(){
        let _this = this;
        return _this.isDeployed;
    }
    /**
     *
     * @param troopGroup {TroopGroup}
     */
    setTroopGroup(troopGroup){
        let _this = this;
        _this.troopGroup = troopGroup;
        _this.troopGroup.addTroop(_this);
    }
    setEffects(es){
        const _this=  this;
        _this.effects = es;
    }
    /**
     *
     * @return {null|*|TroopGroup}
     */
    getTroopGroup(){
        let _this = this;
        return _this.troopGroup;
    }
    getShow(){
      let _this = this;
      return _this.isShow;
    }
    setShow(bool){
        let _this = this;
        if (_this.troopEntity){
            _this.troopEntity.show = bool;
        }
        //效果的显隐
        _this.effects.forEach(e=> {
            e.setShow(bool)
        });
       _this.isShow = bool;
    }
    setState(state){
        let _this =this;
        _this.state = state;
    }
    getState(){
        let _this = this;
        return _this.state;
    }
    prepare(){
        let _this =this;
        console.log("兵力:"+_this.troopName+"---->准备就绪！");

        if (_this.effects.length !== 0){
            for (let effect of _this.effects){
                effect.dynamic();
            }
        }
    }
    gc(){
        let _this =this;
        _this.troopEntity.position = _this.staticPosition;
        _this.state = commonConstants.troopState.Normal;
        if (_this.effects.length !== 0){
            for (let effect of _this.effects){
                effect.gc();
            }
        }
        if (_this.carryTroops.length !== 0){
            for (let i = 0; i < _this.carryTroops.length; i++) {
                let carryTroop = _this.carryTroops[i];
                carryTroop.gc();
                carryTroop.setShow(false);
            }
        }
        console.log("兵力:"+_this.troopName+"---->回收完成！");
    }
    reset(){

    }
    effectRender(){
        let _this = this;
        if (_this.effects.length !== 0){
            for (let effect of _this.effects){
                effect.renderEffect();
            }
        }
    }

    destroy(v) {
        let _this = this;
        _this.effects.forEach(e=> e.destroy())
        v.entities.remove(_this.troopEntity);
        _this.isDestroyed = true;

    }
    toJson() {
        let _this = this;
        let carryIds = [];
        for (let i = 0; i < _this.carryTroops.length; i++) {
            carryIds.push(_this.carryTroops[i].getTroopId());
        }
        return{
            troopId:_this.troopId,
            troopName:_this.troopName,
            troopType:_this.troopType.getTroopTypeId(),
            troopCamp:_this.troopCamp,
            troopScutcheon:_this.troopScutcheon?_this.troopScutcheon:"",
            troopModel:_this.troopModel?_this.troopModel:"",
            troopPosition:_this.staticPosition?CommonMethod.toJsonForPosition(_this.staticPosition):"",
            belongTroopId:_this.belongTroop?_this.belongTroop.getTroopId():"",
            commandTroopId:_this.commandTroop.getTroopId(),
            carryTroopIds:carryIds,
            troopGroupId:_this.troopGroup?_this.troopGroup.getTroopGrooupId():"",
        }
    }

}

export default TroopManager;